package com.fengye.aop.demo.aspect;

import com.fengye.aop.demo.anotation.WorkflowAnnotation;
import com.fengye.aop.demo.enums.OperationType;
import com.fengye.aop.demo.service.account.IWorkflowService;
import com.fengye.aop.demo.vo.WorkflowVO;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

/**
 * @author fengyexjtu@126.com
 * @since 2022-09-23
 */
@Component
@Aspect
@Slf4j
public class WorkflowAspect {
    
    @Autowired
    IWorkflowService workflowService;
    
    @Autowired
    ApplicationEventPublisher eventPublisher;
    
    // @Pointcut(value = "@annotation(com.fengye.aop.demo.anotation.WorkflowAnnotation)")
    @Pointcut(value = "execution(* com.fengye.aop.demo..*.*Service.*(..)) && @annotation(com.fengye.aop.demo.anotation.WorkflowAnnotation)")
    public void pointcut() {
    }
    
    
    @AfterThrowing(pointcut = "pointcut()", throwing = "exce")
    public void handleException(JoinPoint joinPoint, Exception exec) {
        String name = joinPoint.getSignature().getName();
        log.info("发生了异常,name={}", name);
    }
    
    @Before(value = "pointcut()", argNames = "joinPoint,workflowAnnotation")
    public void beforeAnnotation(JoinPoint joinPoint, WorkflowAnnotation workflowAnnotation) {
        // pointcut
        Object[] args = joinPoint.getArgs();
        log.info("before =====在方法执行之前=======,参数为 {}", args);
        
    }
    
    @AfterReturning(value = "pointcut()", returning = "result")
    public void after(JoinPoint joinPoint, Object result) throws Throwable {
        // Object[] args = proceedingJoinPoint.getArgs();
        // System.out.println("args = " + Arrays.toString(args));
        //
        // Object target = proceedingJoinPoint.getTarget();
        // System.out.println("target = " + target);
        //
        // Object result = proceedingJoinPoint.proceed();
        // System.out.println("aop result = " + result);
        // return result;
        
        WorkflowVO workflowVO = (WorkflowVO) result;
        OperationType.event(workflowService, eventPublisher, workflowVO);
        
        workflowService.recordLog(workflowVO);
    }
}
